// *** sample main.cpp: ***
/***********************************************************

	#include <dalelib/utils/glfwapp.h>
	using namespace dalelib;

	class MyApp : public GLFWApp
	{
	public:
		void init(int argc,char** argv) { }
		void setup() { }
		void setdown() { }
		void update() { }
		void draw() { }
	};

	RUN_PROGRAM(MyApp)

***********************************************************/

#ifndef __APP_H__
#define __APP_H__

#include <dalelib/graphics.h>
#include <GL/glfw.h>

#include <string>
using namespace std;

class GLFWApp
{
protected:

	int _frame;
	int _width;
	int _height;
	bool _finished;
	bool _paused;
	string _title;
	GLbitfield _clear_flags;
	int _depth_bits;
	int _stencil_bits;
	int _screen_mode;

public:

	GLFWApp()
	{ }

	virtual ~GLFWApp() { }

	virtual void init(int argc,char** argv) { }

	virtual void setup() { }

	virtual void setdown() { }

	virtual void update() { }

	virtual void draw() { }

	virtual bool checkQuit()
	{
		return ((glfwGetKey(GLFW_KEY_ESC)==GLFW_PRESS) && glfwGetWindowParam(GLFW_OPENED));
	}

	int doIt(int argc,char** argv)
	{
		_frame = 0;
		_width = 512;
		_height = 512;
		_finished = false;
		_paused = false;
		_title = "Shell";
		_clear_flags = GL_COLOR_BUFFER_BIT;
		_depth_bits = 0;
		_stencil_bits = 0;
		_screen_mode = GLFW_WINDOW;

		glfwInit();
		init(argc,argv);
		if( !glfwOpenWindow( _width, _height, 0, 0, 0, 0, _depth_bits, _stencil_bits, _screen_mode ) ) { glfwTerminate(); return -1; }
		glfwSetWindowTitle(_title.c_str());
		setup();
		while(!_finished)
		{
			_frame++;
			glfwGetWindowSize( &_width, &_height );
			_height = _height > 0 ? _height : 1;
			glViewport( 0, 0, _width, _height );
			glClear( _clear_flags );
			if( !_paused ) update();
			draw();
			glfwSwapBuffers();
			if( glfwGetKey('P')==GLFW_PRESS ) { _paused = !_paused; Sleep(200); }
			if( glfwGetKey(GLFW_KEY_ESC)==GLFW_PRESS && glfwGetWindowParam(GLFW_OPENED) ) _finished = true;
		}
		glfwTerminate();
		setdown();
		return 0;
	}

};



#define RUN_PROGRAM(T) 		int main(int argc,char** argv) \
							{ \
								srand(time(0)); \
								T* app = new T; \
								int ret = app->doIt(argc,argv); \
								delete app; \
								return ret; \
							}

#endif // __APP_H__
